package com.yzw.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yzw.dao.SysUserMapper;
import com.yzw.dao.SysUserRoleMapper;
import com.yzw.dto.DataGridResult;
import com.yzw.dto.QueryDTO;
import com.yzw.pojo.SysRole;
import com.yzw.pojo.SysUser;
import com.yzw.pojo.SysUserRole;
import com.yzw.pojo.SysUserRoleExample;
import com.yzw.service.SysRoleService;
import com.yzw.service.SysUserService;
import com.yzw.utils.R;
import com.yzw.utils.UserRegisteAndLogin;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.management.relation.Role;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    SysUserRoleMapper sysUserRoleMapper;
    @Override
    public List<SysUser> findAll() {
        return sysUserMapper.selectByExample(null);
    }

    @Override
    public DataGridResult findUserByPage(QueryDTO queryDTO) {
        PageHelper.offsetPage(queryDTO.getOffset(),queryDTO.getLimit());
        if(queryDTO.getSort()!=null&&!queryDTO.getSort().equals("")){
            queryDTO.setSort("user_id");
        }
        List<SysUser> byPage = sysUserMapper.findByPage(queryDTO);
        PageInfo<SysUser> info = new PageInfo<>(byPage);
        long total = info.getTotal();
        DataGridResult result = new DataGridResult(total,info.getList());
        return result;
    }

    @Override
    public Workbook exportUser() {
        //1，创建了一个空的excel文件
        Workbook workbook = new HSSFWorkbook();
        //2,填充数据：创建sheet
        Sheet sheet = workbook.createSheet("某某公司的员工信息");
        //标题数组
        String titles[] ={"用户id","用户名","邮箱","电话","创建时间"};
        String colums[] ={"userId", "username", "email", "mobile", "createTime"};
        List<Map<String, Object>> maps = sysUserMapper.exportUser();
        Row rowTile = sheet.createRow(0);
        //标题行
        for (int i = 0; i <titles.length ; i++) {
            Cell cell = rowTile.createCell(i);
            cell.setCellValue(titles[i]);
        }
        //遍历数据填充到单元格
        for (int i = 0; i <maps.size() ; i++) {
            //一条记录应该创建一个Row对象 这里从第二行开始所以+1
            Row row = sheet.createRow(i+1);//这个是空的，需要填充数据
            //填充单元格
            for (int j = 0; j < titles.length; j++) {
                Cell cell = row.createCell(j);
                //获取用户id的值
                Map<String, Object> rowValue = maps.get(i);
                //循环动态设置多个字段的值
                Object o = rowValue.get(colums[j]);//这里获取的值可以是"userId"..
                //这里也就是为什么查询数据库使用map封装的原因。
                cell.setCellValue(o+"");
            }
        }
        return workbook;
    }

    @Override
    public SysUser findByUsername(String username) {
        return sysUserMapper.findByUsername(username);
    }

    /**
     * 新增用户
     * @param sysUser
     * @return
     */
    @Override
    public R saveUser(SysUser sysUser) {
        if (sysUser==null){
            return R.error("新增失败");
        }
        sysUser.setCreateTime(new Date());
        String[] saltAndPassword = UserRegisteAndLogin.encryptPassword(sysUser.getUsername(), "123456");
        sysUser.setSalt(saltAndPassword[0]);
        sysUser.setPassword(saltAndPassword[1]);
        byte status = 1;
        sysUser.setStatus(status);
        int i = sysUserMapper.insertSelective(sysUser);
        SysUserRole sysUserRole = new SysUserRole();
        sysUserRole.setUserId(sysUser.getUserId());
        sysUserRole.setRoleId(sysUser.getRoleId().longValue());
        sysUserRoleMapper.insertSelective(sysUserRole);
        return i>0?R.ok():R.error("新增失败");
    }

    /**
     * 删除用户
     * @param ids
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public R deleteMenu(List<Long> ids) {
        for (Long id : ids) {
            if (id<=3){
                return R.error("系统用户，不允许删除");
            }
        }
        int i = sysUserMapper.deleteUser(ids);
        return i>0?R.ok():R.error("删除失败");
    }

    @Override
    public R findUserById(long userId) {
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(userId);
        return R.ok().put("user",sysUser);
    }

    @Override
    public int update(SysUser sysUser) {
//        String[] saltAndPassword = UserRegisteAndLogin.encryptPassword(sysUser.getUsername(), sysUser.getPassword());
//        sysUser.setSalt(saltAndPassword[0]);
//        sysUser.setPassword(saltAndPassword[1]);
        int i = sysUserMapper.updateByPrimaryKeySelective(sysUser);
        SysUserRole userRole = new SysUserRole();
        userRole.setRoleId(sysUser.getRoleId().longValue());
        SysUserRoleExample example = new SysUserRoleExample();
        SysUserRoleExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(sysUser.getUserId());
        sysUserRoleMapper.updateByExampleSelective(userRole,example);
        return i;
    }

    @Override
    public R password(String password, String newPassword) {
        try {
            //获得当前用户
            Subject subject = SecurityUtils.getSubject();
            SysUser user = (SysUser) subject.getPrincipal();
            //获得token
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),password);
            subject.login(token);
            //如果通过认证，就把前端传过来的新密码加密
            String[] strings = UserRegisteAndLogin.encryptPassword(user.getUsername(), newPassword);
            //获得盐
            String salt = strings[0];
            //获得加密后的密码
            String encPassword = strings[1];

            user.setSalt(salt);
            user.setPassword(encPassword);
            //修改
            sysUserMapper.updateByPrimaryKeySelective(user);
            return R.ok("修改成功");
        } catch (IncorrectCredentialsException e) {
            return R.error("原密码错误");
        }catch (LockedAccountException e){
            return R.error("账号被冻结");
        }


    }

    @Override
    public R selectByUserId(long userId) {
        SysUser sysUser = sysUserMapper.selectByUserId(userId);
        return R.ok().put("user",sysUser);
    }
}
